1. /* slfcmbpf.cpp by K.Tsuru */
  2. // function ID 4107 DRADIX since ver 2.182
  3. // first version made on 24 Apr 2010
  4. // remade on 10 Oct 2016 ver 2.30
  5. /****************************************************************
  6. The combination number(binomial function )
  7. n!
  8. nCr = ---------
  9. r!(n-r)!
  10. *****************************************************************/
  11. #ifndef SN_H
  12. #include "sn.h"
  13. #endif
  14. // defined as "const long nMax_combD = 48L;" in "tools.h"
  15. // "const ulong nMax_combL = 2000UL;" in "snmath.h"
  16. SLong comb(ulong n, ulong k){ // combination number(binomial) nCk
  17. if( n < k ) SNManager::SetError(SNManager::DOMAIN_ERR, "comb()", 4102);
  18. if(n <= nMax_combD) return (SLong)combD(n, k); // <= 48 uses double vesion
  19. if(n < nMax_combL) return combL(n,k); // =2000
  20. return combPF(n,k);
  21. }
  22. /****************************************
  23. PF(Prime factor) method
  24. nCr is evaluated by prime factorization of n!, reduction and product
  25. refer to GMP's factorial algorithm using prime factorization
  26. It makes the prime table between 2 and n
  27. using the sieve of Eratosthenes.
  28. *****************************************/
  29. // for sorting
  30. static int sortByPower(const void *e1, const void *e2) {
  31. return (int)((const primeFactor *)e2)->power - (int)((const primeFactor *)e1)->power;
  32. }
  33. SLong combPF(const ulong n, const ulong r) {
  34. if( (r == 0) || (n == r) ) return 1.0;
  35. if( n < r ) SNManager::SetError(SNManager::DOMAIN_ERR,"combPF()", 4107);
  36. SNBlock<primeFactor> npf, rpf, n_rpf;
  37. int in = FactorialIntoPrimeFactor(n, npf); // number of prime factor n!
  38. int ir = FactorialIntoPrimeFactor(r, rpf); // r!
  39. int in_r = FactorialIntoPrimeFactor(n - r, n_rpf);// (n-r)!
  40. // reduction
  41. for(int k = 0; k < ir; k++) npf[k].power -= rpf(k).power;
  42. for(int k = 0; k < in_r; k++) npf[k].power -= n_rpf(k).power;
  43. int non0pwr = 0; // number of non zero power elements
  44. for(int k = 0; k < in; k++) {
  45. if(npf(k).power) non0pwr++;
  46. }
  47. // pick out nonzero power elements
  48. primeFactor* wpf = new primeFactor[non0pwr+1];
  49. int el = 0;
  50. for(int k = 0; k < in; k++) {
  51. if(npf[k].power) { wpf[el] = npf(k); el++; }
  52. }
  53. wpf[el].prime = wpf[el].power = 0; // index of last element
  54. qsort(wpf, non0pwr, sizeof(primeFactor), sortByPower);
  55. SNBlock<primeFactor> pfBk(el+1);
  56. for(int k = 0; k <= el; k++) pfBk[k] = wpf[k];
  57. SLong p = PrimeFactorProduct(pfBk, el);
  58. delete[] wpf;
  59. return p;
  60. }

slfcmbpf.cpp : last modifiled at 2017/02/25 09:37:22(2,442 bytes)
created at 2017/10/07 10:26:50
The creation time of this html file is 2017/11/09 14:52:03 (Thu Nov 09 14:52:03 2017).